home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_092 / as6502 / assm2.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  512 lines

  1. #include "stdio.h"
  2. #include "assm.d1"
  3. #include "assm.d2"
  4. #include "ctype.h"
  5.  
  6. extern    int    optab[];
  7. extern    int    step[];
  8.  
  9. /* translate source line to machine language */
  10.  
  11. assemble()
  12. {
  13.     int    flg;
  14.     int    i;        /* prlnbuf pointer */
  15.  
  16.     if ((prlnbuf[SFIELD] == ';') | (prlnbuf[SFIELD] == 0)) {
  17.         if (pass == LAST_PASS)
  18.             println();
  19.         return;
  20.     }
  21.     lablptr = -1;
  22.     i = SFIELD;
  23.     udtype = UNDEF;
  24.     if (colsym(&i) != 0 && (lablptr = stlook()) == -1)
  25.         return;
  26.     while (prlnbuf[++i] == ' ');    /* find first non-space */
  27.     if ((flg = oplook(&i)) < 0) {    /* collect operation code */
  28.         labldef(loccnt);
  29.         if (flg == -1)
  30.             error("Invalid operation code");
  31.         if ((flg == -2) && (pass == LAST_PASS)) {
  32.             if (lablptr != -1)
  33.                 loadlc(loccnt, 1, 0);
  34.             println();
  35.         }
  36.         return;
  37.     }
  38.     if (opflg == PSEUDO)
  39.         pseudo(&i);
  40.     else if (labldef(loccnt) == -1)
  41.         return;
  42.     else {
  43.         if (opflg == CLASS1)
  44.             class1();
  45.         else if (opflg == CLASS2)
  46.             class2(&i);
  47.         else class3(&i);
  48.     }
  49. }
  50.  
  51. /****************************************************************************/
  52.  
  53. /* printline prints the contents of prlnbuf */
  54.  
  55. println()
  56. {
  57.     if (lflag > 0)
  58.         {
  59.         if (paglin == pagesize) printhead();
  60.         prlnbuf[linesize] = '\0';
  61.         fprintf(stdout, "%s\n", prlnbuf);
  62.         paglin++ ;
  63.         }
  64. }
  65.  
  66. /****************************************************************************/
  67.  
  68. /* printhead prints the page heading   */
  69.  
  70. printhead()
  71. {
  72.     if (pagesize == 0) return;
  73.     pagect++ ;
  74.     fprintf(stdout, "\f\nAmiga 6502 assembler :  -  %s PAGE %d\n",
  75.     titlbuf,pagect);
  76.     fprintf(stdout, "Line      Location     Label Opcode Operand  Comment   %s\n\n",date);
  77.     paglin = 0;
  78. }
  79.  
  80. /* colsym() collects a symbol from prlnbuf into symbol[],
  81.  *    leaves prlnbuf pointer at first invalid symbol character,
  82.  *    returns 0 if no symbol collected
  83.  */
  84.  
  85. colsym(ip)
  86.     int *ip;
  87. {
  88.     int    valid;
  89.     int    i;
  90.     char    ch;
  91.  
  92.     valid = 1;
  93.     i = 0;
  94.     while (valid == 1) {
  95.         ch = prlnbuf[*ip];
  96.         if (ch == '_' || ch == '.');
  97.         else if (ch >= 'a' && ch <= 'z');
  98.         else if (ch >= 'A' && ch <= 'Z');
  99.         else if (i >= 1 && ch >= '0' && ch <= '9');
  100.         else if (i == 1 && ch == '=');
  101.         else valid = 0;
  102.         if (valid == 1) {
  103.             if (i < SBOLSZ - 1)
  104.                 symbol[++i] = ch;
  105.             (*ip)++;
  106.         }
  107.     }
  108.     if (i == 1) {
  109.         switch (symbol[1]) {
  110.         case 'A': case 'a':
  111.         case 'X': case 'x':
  112.         case 'Y': case 'y':
  113.             error("Symbol is reserved (A, X or Y)");
  114.             i = 0;
  115.         }
  116.     }
  117.     symbol[0] = i;
  118.     return(i);
  119. }
  120.  
  121. /* symbol table lookup
  122.  *    if found, return pointer to symbol
  123.  *    else, install symbol as undefined, and return pointer
  124.  */
  125.  
  126. stlook()
  127. {
  128. int ptr, ln, eq;
  129. ptr = 0;
  130. while (ptr < nxt_free)
  131.     {
  132.     ln = symbol[0]; if (symtab[ptr] < ln) ln = symtab[ptr];
  133.     if ((eq = strncmp(&symtab[ptr+1], &symbol[1], ln)) == 0 &&
  134.        symtab[ptr] == symbol[0]) return ptr;
  135.     if (eq > 0) return(stinstal(ptr));
  136.     ptr = ptr+6+ symtab[ptr];
  137.     ptr = ptr +1 + 2*(symtab[ptr] & 0xff);
  138.     }
  139. return (stinstal(ptr));
  140. }
  141.  
  142.  
  143. /*  instal symbol into symtab
  144.  */
  145.  
  146. stinstal(ptr)
  147. int ptr;
  148. {
  149. int ptr2, i;
  150. if (openspc(ptr,symbol[0]+7) == -1) {
  151.     error("Symbol Table Full"); /* print error msg and ...  */
  152.     pass = DONE;            /* cause termination of assembly */
  153.     return -1; }
  154. ptr2 = ptr;
  155. for (i=0; i< symbol[0]+1; i++)
  156.     symtab[ptr2++] = symbol[i];
  157. symtab[ptr2++] = udtype;
  158. symtab[ptr2+4] = 0;
  159. return(ptr);
  160. }
  161.  
  162.  
  163. /*   addref : add a reference line to the  symbol pointed to    */
  164. /*            by ip.                        */
  165.  
  166. addref(ip)
  167. int ip;
  168. {
  169. int rct, ptr;
  170. rct = ptr =ip + symtab[ip] + 6;
  171. if ((symtab[rct] & 0xff) == 255) {    /* non-fatal error   */
  172.     fprintf(stderr,"%s\n",prlnbuf);
  173.     fprintf(stderr,"Too many references\n");
  174.     return; }
  175. ptr += (symtab[rct] & 0xff) * 2 +1;
  176. if (openspc(ptr,2) == -1) {
  177.     error("Symbol Table Full");
  178.     return -1; }
  179. symtab[ptr] = slnum & 0xff;
  180. symtab[ptr+1] = (slnum >> 8) & 0xff;
  181. symtab[rct]++;
  182. }
  183.  
  184.  
  185. /* openspc : open up a space in the symbol table        */
  186. /*           the space will be at (ptr) and will be     */
  187. /*           len characters long. return -1 if no room. */
  188.  
  189. openspc(ptr,len)
  190. int ptr,len;
  191. {
  192. int ptr2, ptr3;
  193. if (nxt_free + len > size) return -1;
  194. if (ptr != nxt_free)
  195.     {
  196.     ptr2 = nxt_free -1;
  197.     ptr3 = ptr2 + len;
  198.     while (ptr2 >= ptr) symtab[ptr3--] = symtab[ptr2--];
  199.     }
  200. nxt_free += len;
  201. if (lablptr >= ptr) lablptr += len;
  202. return 0;
  203. }
  204.  
  205.  
  206. /* operation code table lookup
  207.  *    if found, return pointer to symbol,
  208.  *    else, return -1
  209.  */
  210.  
  211. oplook(ip)
  212.    int    *ip;
  213. {
  214. register    char    ch;
  215. register    int    i;
  216. register    int    j;
  217.     int    k;
  218.     int    temp[2];
  219.  
  220.     i = j = 0;
  221.     temp[0] = temp[1] = 0;
  222.     while((ch=prlnbuf[*ip])!= ' ' && ch!= 0 && ch!= '\t' && ch!= ';') {
  223.         if (ch >= 'A' && ch <= 'Z')
  224.             ch &= 0x1f;
  225.         else if (ch >= 'a' && ch <= 'z')
  226.             ch &= 0x1f;
  227.         else if (ch == '.')
  228.             ch = 31;
  229.         else if (ch == '*')
  230.             ch = 30;
  231.         else if (ch == '=')
  232.             ch = 29;
  233.         else return(-1);
  234.         temp[j] = (temp[j] * 0x20) + (ch & 0xff);
  235.         if (ch == 29)
  236.             break;
  237.         ++(*ip);
  238.         if (++i >= 3) {
  239.             i = 0;
  240.             if (++j >= 2) {
  241.                 return(-1);
  242.             }
  243.         }
  244.     }
  245.     if ((j = temp[0]^temp[1]) == 0)
  246.         return(-2);
  247.     k = 0;
  248.     i = step[k] - 3;
  249.     do {
  250.         if (j == optab[i]) {
  251.             opflg = optab[++i];
  252.             opval = optab[++i];
  253.             return(i);
  254.         }
  255.         else if (j < optab[i])
  256.             i -= step[++k];
  257.         else i += step[++k];
  258.     } while (step[k] != 0);
  259.     return(-1);
  260. }
  261.  
  262. /* error printing routine */
  263.  
  264. error(stptr)
  265.    char *stptr;
  266. {
  267.     loadlc(loccnt, 0, 1);
  268.     loccnt += 3;
  269.     loadv(0,0,0);
  270.     loadv(0,1,0);
  271.     loadv(0,2,0);
  272.     fprintf(stderr, "%s\n", prlnbuf);
  273.     fprintf(stderr, "%s\n", stptr);
  274.     errcnt++;
  275. }
  276.  
  277. /* load 16 bit value in printable form into prlnbuf */
  278.  
  279. loadlc(val, f, outflg)
  280.     int val;
  281.     int f;
  282.     int outflg;
  283. {
  284.     int    i;
  285.  
  286.     i = 6 + 7*f;
  287.     hexcon(4, val);
  288.     if (nflag == 0) {
  289.         prlnbuf[i++]  = hex[3];
  290.         prlnbuf[i++]  = hex[4];
  291.         prlnbuf[i++]  = ':';
  292.         prlnbuf[i++]  = hex[1];
  293.         prlnbuf[i] = hex[2];
  294.     }
  295.     else {
  296.         prlnbuf[i++] = hex[1];
  297.         prlnbuf[i++] = hex[2];
  298.         prlnbuf[i++] = hex[3];
  299.         prlnbuf[i] = hex[4];
  300.     }
  301.     if ((pass == LAST_PASS)&&(oflag != 0)&&(objcnt <= 0)&&(outflg != 0))
  302.         {
  303.         if (mflag != 0) start_obj(val);
  304.         else fprintf(optr, "\n;%c%c%c%c", hex[3], hex[4], hex[1], hex[2]);
  305.         objcnt=22;
  306.         }
  307. }
  308.  
  309.  
  310.  
  311. /* load value in hex into prlnbuf[contents[i]] */
  312. /* and output hex characters to obuf if LAST_PASS & oflag == 1 */
  313.  
  314. loadv(val,f,outflg)
  315.    int    val;
  316.    int    f;        /* contents field subscript */
  317.    int    outflg;        /* flag to output object bytes */
  318. {
  319.  
  320.     hexcon(2, val);
  321.     prlnbuf[13 + 3*f] = hex[1];
  322.     prlnbuf[14 + 3*f] = hex[2];
  323.     if ((pass == LAST_PASS) && (oflag != 0) && (outflg != 0)) {
  324.         if (mflag != 0) put_obj(val);
  325.         else {    fputc(hex[1], optr);
  326.             fputc(hex[2], optr); }
  327.         --objcnt;
  328.     }
  329. }
  330.  
  331. /* convert number supplied as argument to hexadecimal in hex[digit] (lsd)
  332.         through hex[1] (msd)        */
  333.  
  334. hexcon(digit, num)
  335.     int digit;
  336.    int    num;
  337. {
  338.  
  339.     for (; digit > 0; digit--) {
  340.         hex[digit] = (num & 0x0f) + '0';
  341.         if (hex[digit] > '9')
  342.             hex[digit] += 'A' -'9' - 1;
  343.         num >>= 4;
  344.     }
  345. }
  346.  
  347. /* assign <value> to label pointed to by lablptr,
  348.  *    checking for valid definition, etc.
  349.  */
  350.  
  351. labldef(lval)
  352.     int lval;
  353. {
  354.     int    i;
  355.  
  356.     if (lablptr != -1) {
  357.         lablptr += symtab[lablptr] + 1;
  358.         if (pass == FIRST_PASS) {
  359.             if (symtab[lablptr] == UNDEF) {
  360.                 symtab[lablptr + 1] = lval & 0xff;
  361.                 i = symtab[lablptr + 2] = (lval >> 8) & 0xff;
  362.                 if (i == 0)
  363.                     symtab[lablptr] = DEFZRO;
  364.                 else    symtab[lablptr] = DEFABS;
  365.             }
  366.             else if (symtab[lablptr] == UNDEFAB) {
  367.                 symtab[lablptr] = DEFABS;
  368.                 symtab[lablptr + 1] = lval & 0xff;
  369.                 symtab[lablptr + 2] = (lval >> 8) & 0xff;
  370.             }
  371.             else {
  372.                 symtab[lablptr] = MDEF;
  373.                 symtab[lablptr + 1] = 0;
  374.                 symtab[lablptr + 2] = 0;
  375.                 error("Label multiply defined");
  376.                 return(-1);
  377.             }
  378.         symtab[lablptr+3] = slnum & 0xff;
  379.         symtab[lablptr+4] = (slnum >> 8) & 0xff;
  380.         }
  381.         else {
  382.             i = (symtab[lablptr + 2] << 8) +
  383.                 (symtab[lablptr+1] & 0xff);
  384.             i &= 0xffff;
  385.             if (i != lval && pass == LAST_PASS) {
  386.                 error("Sync error");
  387.                 return(-1);
  388.             }
  389.         }
  390.     }
  391.     return(0);
  392. }
  393.  
  394. /* determine the value of the symbol,
  395.  * given pointer to first character of symbol in symtab
  396.  */
  397.  
  398. symval(ip)
  399.     int *ip;
  400. {
  401.     int    ptr;
  402.     int    svalue;
  403.  
  404.     svalue = 0;
  405.     colsym(ip);
  406.     if ((ptr = stlook()) == -1)
  407.         undef = 1;        /* no room error */
  408.     else if (symtab[ptr + symtab[ptr] + 1] == UNDEF)
  409.         undef = 1;
  410.     else if (symtab[ptr + symtab[ptr] + 1] == UNDEFAB)
  411.         undef = 1;
  412.     else svalue = ((symtab[ptr + symtab[ptr] + 3] << 8) +
  413.         (symtab[ptr + symtab[ptr] + 2] & 0xff)) & 0xffff;
  414.     if (symtab[ptr + symtab[ptr] + 1] == DEFABS)
  415.         zpref = 1;
  416.     if (undef != 0)
  417.         zpref = 1;
  418.  
  419.     /* add a reference entry to symbol table on first pass only,
  420.        except for branch instructions (CLASS2) which do not come
  421.        through here on the first pass                            */
  422.     if (ptr >= 0 && pass == FIRST_PASS) addref(ptr);
  423.     if (ptr >= 0 && opflg == CLASS2) addref(ptr); /* branch addresses */
  424.     return(svalue);
  425. }
  426.  
  427. /*    object code record generation routines    */
  428. /*    added to generate MOS Technology format   */
  429. /*       object records                         */
  430. /*           By Joel Swank 12/86                */
  431.  
  432. char obj_rec[60];        /* buffer for object record */
  433. unsigned  obj_ptr = 0;        /* pointer for above  */
  434. unsigned  obj_bytes = 0;        /* count of bytes in current record */
  435. unsigned  rec_cnt = 0;        /* count of records in this file */
  436. unsigned  cksum = 0;            /* record check sum accumulator  */
  437.  
  438. /*   put one object byte in hex   */
  439.  
  440. put_obj(val)
  441. unsigned val;
  442. {
  443.     hexcon(2,val);
  444.     obj_rec[obj_ptr++] = hex[1];
  445.     obj_rec[obj_ptr++] = hex[2];
  446.     cksum += (val & 0xff);
  447.     obj_bytes++;
  448. }
  449.  
  450.  
  451. /*    start an object record (end previous) */
  452.  
  453. start_obj(val)
  454. unsigned val;     /*  current location counter */
  455. {
  456.     prt_obj();    /* print the current record if any */
  457.     hexcon(4,val);
  458.     obj_bytes=0;
  459.     for (obj_ptr=0; obj_ptr<4; obj_ptr++) obj_rec[obj_ptr] = hex[obj_ptr+1];
  460.     cksum = (val>>8) + (val & 0xff);
  461.     rec_cnt++;
  462. }
  463.  
  464.  
  465. /*    print the current object record if any */
  466.  
  467. prt_obj()
  468. {
  469.     if (obj_bytes == 0) return;
  470.     cksum += obj_bytes;
  471.     hexcon(2,obj_bytes);
  472.     obj_rec[obj_ptr] = '\0';
  473.     fprintf(optr,";%c%c%s",hex[1],hex[2],obj_rec);
  474.     hexcon(4,cksum);
  475.     fprintf(optr,"%c%c%c%c\n",hex[1],hex[2],hex[3],hex[4]);
  476. }
  477.  
  478.  
  479. /*    finish object file       */
  480.  
  481. fin_obj()
  482. {
  483.     unsigned i;
  484.     prt_obj();
  485.     hexcon(4,++rec_cnt);
  486.     fprintf(optr,";00");
  487.     for (i=1; i<5; i++) fputc(hex[i],optr);
  488.     rec_cnt = rec_cnt/256 + (rec_cnt & 0xff);
  489.     hexcon(4,rec_cnt);
  490.     for (i=1; i<5; i++) fputc(hex[i],optr);
  491.     fputc('\n',optr);
  492. }
  493. /*     MOS Tech. object format is as follows    */
  494. /*
  495.     ( all data is in ASCII encoded hexidecimal)
  496.  
  497.  Data record : ;nnaaaadddd...xxxx[cr]
  498.  Last record : ;00ccccxxxx[cr]
  499.  
  500.  Where:
  501.     ;    = Start of record (ASCII 3B)
  502.     nn    = Number of data bytes in the record.
  503.           max = 24 bytes.
  504.     aaaa    = address of first data byte in the record.
  505.     dd    = 1 data byte.
  506.     xxxx    = checksum that is the twos compliment sum of all
  507.           data bytes, the count byte and the address bytes.
  508.     cccc    = count of records in the file.
  509.     [cr]    = ASCII Carriage Return (ASCII 0D).
  510.  
  511. */
  512.